
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;

namespace Swaf
{
	/// <summary>
	/// A simple class to represent two numbers that is typically used for points and sizes
	/// in drawing type calculations.
	/// </summary>
	public class NumericPair
	{
		int m_num1, m_num2;

		/// <summary>
		/// Default initialization to 0,0
		/// </summary>
		public NumericPair()
			:this(0,0)
		{
			//Intentionally left blank
		}

		/// <summary>
		/// Initize pair to the numbers provided.
		/// </summary>
		/// <param name="num1">Assigned to first number in pair</param>
		/// <param name="num2">Assigned to second number in pair</param>
		public NumericPair(int num1, int num2)
		{
			m_num1 = num1;
			m_num2 = num2;
		}

		/// <summary>
		/// Provides a number from the pair based on the index i, which must be either 1 or 0.
		/// </summary>
		public int this[int i]
		{
			get
			{
				if(i > 1)
					throw new BaseException("Invalid param: value out of range");
				return (i == 0)?m_num1:m_num2;
			}
			set
			{
				switch(i)
				{
					case 0: m_num1 = value;break;
					case 1: m_num2 = value;break;
					default: throw new BaseException("Invalid param: value out of range");
				}
			}
		}

		/// <summary>
		/// Compares the given NumericPair against this one.  Returns true if both numbers in each pair match
		/// accordingly.
		/// </summary>
		/// <param name="obj">The NumericPair instance to compair against</param>
		/// <returns>Their calculated equality</returns>
		public override bool Equals(object obj)
		{
			if(!(obj is NumericPair))
				return false;
			NumericPair other = (NumericPair)obj;
			return (other.m_num1 == m_num1 && other.m_num2 == m_num2);
		}


		/// <summary>
		/// Basic property for getting/setting the first value in the numeric pair
		/// </summary>
		public int Num1
		{
			get{return m_num1;}
			set{m_num1 = value;}
		}

		/// <summary>
		/// Basic property for getting/setting the second value in the numeric pair
		/// </summary>
		public int Num2
		{
			get{return m_num2;}
			set{m_num2 = value;}
		}
	}

	/// <summary>
	/// A simple rectangle based on the NumericPair class.  Together, these classes make it
	/// easy to use indexers to get at the values of the rectangle.  
	/// </summary>
	/// <remarks>This can make sizing algorythms easier to write then using the .NET point and Rectangle classes
	/// from the System.Drawing namespace.</remarks>
	public class Rect
	{
		NumericPair m_pos;
		NumericPair m_size;

		/// <summary>
		/// Default initialization to 0,0,0,0
		/// </summary>
		public Rect()
			:this(0,0,0,0)
		{
			//Intentionally left blank
		}

		/// <summary>
		/// Initializes the rectangle to the deminsions provided
		/// </summary>
		/// <param name="x">Maps to position.Num1</param>
		/// <param name="y">Maps to position.Num2</param>
		/// <param name="w">Maps to size.Num1</param>
		/// <param name="h">Maps to size.Num2</param>
		public Rect(int x, int y, int w, int h)
		{
			m_pos = new NumericPair(x,y);
			m_size = new NumericPair(w,h);
		}

		/// <summary>
		/// Compairs the given Rect object's equality to this one
		/// </summary>
		/// <param name="obj">The instance of Rect to compair against</param>
		/// <returns>The calculated equality</returns>
		public override bool Equals(object obj)
		{
			if(!(obj is Rect))
				return false;
			Rect other = (Rect)obj;
			return (m_pos.Equals(other.m_pos) && m_size.Equals(other.m_size));
		}


		public NumericPair this[int i]
		{
			get
			{
				if(i > 1)
					throw new Exception("Invalid param: value out of range");
				return (i==0)?m_pos:m_size;
			}
			set
			{
				switch(i)
				{
					case 0: m_pos = value;break;
					case 1: m_size = value;break;
					default: throw new Exception("Invalid param: value out of range");
				}
			}
		}

		public NumericPair Position 
		{
			get{return m_pos;}
			set{m_pos = value;}
		}
		public NumericPair Size 
		{
			get{return m_size;}
			set{m_size = value;}
		}

		public bool contains(NumericPair point)
		{
			return 
				(m_pos.Num1 <= point.Num1 && m_pos.Num2 <= point.Num2 &&
				(m_pos.Num1 + m_size.Num1) >= point.Num1 &&
				(m_pos.Num2 + m_size.Num2) >= point.Num2);
		}
	}
}
